参考资料:https://www.elastic.co/guide/cn/elasticsearch/guide/current/aggregations.html
创建数据
我们先通过模拟的数据来看看有哪些语法。
由于es集群禁止了自动创建索引,我们只能先创建索引。
- 创建索引
1 | PUT /test?pretty |
新增数据
批量插入部分数据。
1 | post /test/test/_bulk |
了解聚合概念
桶(Buckets)
满足特定条件的文档的集合
指标(Metrics)
对桶内的文档进行统计计算。
聚合是由桶和指标组成的。 聚合可能只有一个桶,可能只有一个指标,或者可能两个都有。也有可能有一些桶嵌套在其他桶里面。例如,我们可以通过所属国家来划分文档(桶),然后计算每个国家的平均薪酬(指标)。 另外聚合计算是实时的。一旦文档可以被搜到,它就能被聚合。这也就意味着我们可以直接将聚合的结果源源不断的传入前端,让其动态显示变化。 5.x后对排序,聚合这些操作用单独的数据结构(fielddata)缓存到内存里了,需要单独开启。对哪个字段聚合就要开启哪个字段。比如我就开启了color字段,方便后续的聚合。
1 | PUT test/_mapping/test/ |
根据颜色分组,参考mysql的groupby
1 | GET /cars/transactions/_search |
核心结果如下:
1 | "aggregations" : { |
对桶内的数据计算一下。
1 | GET /test/test/_search |
结果如下:
1 | "aggregations" : { |
希望求出每个颜色里面制造厂商的分布情况,那就里面在嵌套一个桶。
1 | GET /test/test/_search |
结果如下
1 | "aggregations" : { |
条形图
这个关键字histogram,这个关键字要求字段必须是数值类型,然后interval定义了区间,然后可以在加几个指标,来获取这个区间的信息,比如最大值,最小值,和,平均值巴拉巴拉的。
1 | GET /test/test/_search |
结果如下:
1 | "aggregations" : { |
根据时间来聚合数据,首先命名为sales,然后使用关键字date_histogram,选择字段,和时间粒度即可。中间没有的月份也会显示,只是数目为0。
1 | GET /test/test/_search |
结果如下:
1 | "aggregations" : { |
另外由于elasticSearch版本差异太大,2.x版本date_histogram
,histogram
时间聚合和数值聚合返回的buckets是没有空值的,也就是某个月份数据为0或者某个区间值为0,那么返回值里面是没有的(当然可以设置参数让其有),但是目前线上版本是6.x的,默认已经有空值了
下面来一个复杂的聚合,我来解释下其逻辑。
- 首先根据每个季度创建一个桶,然后在每个桶里面在进行聚合计算。
- 在季度每个桶里面第一个指标算出,这个季度一共卖了多少钱。
- 在季度这个桶里面再根据制造厂商创建桶,同时计算出每个厂商卖了多少钱。
1 | GET /test/test/_search |
这是一个稍微复杂点的聚合逻辑,理解了他基本也就理解了全部的概念
结果如下:
1 | "aggregations" : { |
我们可以将查询和聚合一起来使用,前面的聚合查询基本都相当于加了
1 | "query" : { |
下面是个简单例子,是聚合和查询集合的例子。查出ford厂商的卖的车的颜色聚合。
1 | GET /test/test/_search |
我们不仅可以在查询条件内做聚合,还可以全局聚合,同时使用,用法是关键字all
1 | GET /test/test/_search |
结果如下:算出了查询值得平均值,还算出了全部文档的平均值。
1 | "aggregations" : { |
聚合也可以和过滤一起使用。比如这个语句查出大于15000销售额的平均值。
1 | GET /test/test/_search |
结果如下:
1 | "aggregations" : { |
过滤桶,对聚合结果过滤。
先选出ford厂商的车,然后在这个结果里面再进行过滤选出上个月的数据。
1 | GET /test/test/_search |
有一种做法,先查询,然后聚合,再过滤一部分数据,这个过滤不能影响聚合。
1 | GET /test/test/_search |
上面的聚合可以不断嵌套聚合。从而组合成更加复杂的结果
排序的话,下面这个技巧很有意思,可以参考了解下,业务中很有可能用的到。
- 先根据颜色分组,然后算出每一组的平均值,然后再根据平均值排序。
1 | GET /cars/transactions/_search |
统计唯一值
1 | GET /test/test/_search |
这个是统计颜色的种类,es使用了cardinality算法,也就是 HyperLogLog++ 算法做的,他不需要统计全部的数据,然后汇总计算,有误差,但是可以接受,性能可以。
如果统计唯一值得时候对速度要求很高,这块可以优化,参考:https://www.elastic.co/guide/cn/elasticsearch/guide/current/cardinality.html。就是给这些字段建立索引。